package com.linzm.leetcode.primary.exercises4_20230129;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author zimingl
 * @Date 2023/2/1 23:28
 * @Description: 无人机方阵
 * 在 「力扣挑战赛」 开幕式的压轴节目 「无人机方阵」中，每一架无人机展示一种灯光颜色。 无人机方阵通过两种操作进行颜色图案变换：
 * 调整无人机的位置布局
 * 切换无人机展示的灯光颜色
 * 给定两个大小均为 N*M 的二维数组 source 和 target 表示无人机方阵表演的两种颜色图案，由于无人机切换灯光颜色的耗能很大，请返回从 source 到 target 最少需要多少架无人机切换灯光颜色。
 * 注意： 调整无人机的位置布局时无人机的位置可以随意变动。
 * 输入：source = [
 * [1,3],
 * [5,4]], target = [
 * [3,1],[
 * 6,5]]
 * 输出：1
 * 解释： 最佳方案为 将 [0,1] 处的无人机移动至 [0,0] 处； 将 [0,0] 处的无人机移动至 [0,1] 处；
 * 将 [1,0] 处的无人机移动至 [1,1] 处； 将 [1,1] 处的无人机移动至 [1,0] 处，其灯光颜色切换为颜色编号为 6 的灯光； 因此从source 到 target 所需要的最少灯光切换次数为 1。
 * 输入：source = [
 * [1,2,3],
 * [3,4,5]], target = [
 * [1,3,5],
 * [2,3,4]]
 * 输出：0 解释： 仅需调整无人机的位置布局，便可完成图案切换。因此不需要无人机切换颜色
 * 提示： n == source.length == target.length m == source[i].length == target[i].length 1 <= n, m <=100 1 <= source[i][j], target[i][j] <=10^4
 */
public class Demo7_39 {
    public static void main(String[] args) {
        int[][] source = {{3},{3}}, target = {{2},{4}};
        Demo7_39 demo7_39 = new Demo7_39();
        int minimumSwitchingTimes = demo7_39.minimumSwitchingTimes(source, target);
        System.out.println(minimumSwitchingTimes);
    }

    private int minimumSwitchingTimes(int[][] source, int[][] target) {
        Map<Integer, Integer> map1 = new HashMap<>();
        Map<Integer, Integer> map2 = new HashMap<>();
        for (int i = 0; i < source.length; i++) {
            for (int j = 0; j < source[i].length; j++) {
                map1.put(source[i][j], map1.getOrDefault(source[i][j], 0) + 1);
            }
        }
        for (int i = 0; i < target.length; i++) {
            for (int j = 0; j < target[i].length; j++) {
                map2.put(target[i][j], map2.getOrDefault(target[i][j], 0) + 1);
            }
        }
        int count = 0;
        for (Map.Entry entry : map2.entrySet()) {
            Integer num2 = map2.get(entry.getKey());
            Integer num1 = map1.getOrDefault(entry.getKey(), 0);
            if (num2 > num1) {
                count += Math.abs(num2 - num1);
            }
        }
        return count;
    }

    private int minimumSwitchingTimes2(int[][] source, int[][] target) {
        int m = source.length, n = source[0].length;
        int[] cnt = new int[10001];
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                ++cnt[source[i][j]];
            }
        }
        int num = 0;
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                if(cnt[target[i][j]]-- > 0) {
                    ++num;
                }
            }
        }
        return m * n - num;
    }
}
